本篇文章主要介绍 Spring IoC 容器 createBean()
方法流程。
前言 本篇文章主要分析 Spring IoC 的 createBean()
方法的流程,以及 bean
的生命周期。
下面是一个大致的流程图:
正文 AbstractAutowireCapableBeanFactory#createBean 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 @Override protected Object createBean (String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'" ); } RootBeanDefinition mbdToUse = mbd; Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null ) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed" , ex); } try { Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null ) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed" , ex); } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'" ); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation" , ex); } }
上面方法如果 resolveBeforeInstantiation()
返回非 null
,则会跳过后面步骤,直接返回实例。这也是一个扩展点,给 BeanPostProcessor
一个机会来返回代理来替代真正的实例。
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 protected Object resolveBeforeInstantiation (String beanName, RootBeanDefinition mbd) { Object bean = null ; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null ) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null ) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null ); } return bean; }
上面方法主要是判断 bean
之前没有解析过并且有注册 InstantiationAwareBeanPostProcessor
接口,然后这里会调用 bean
实例化前的回调方法,如果返回非空,会调用 bean
实例化后的回调方法;因为返回非空,后续正常的流程都不会走了,所以只能在此处调用。
下面是 InstantiationAwareBeanPostProcessor
接口,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { @Nullable default Object postProcessBeforeInstantiation (Class<?> beanClass, String beanName) throws BeansException { return null ; } default boolean postProcessAfterInstantiation (Object bean, String beanName) throws BeansException { return true ; } @Nullable default PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) throws BeansException { return null ; } @Deprecated @Nullable default PropertyValues postProcessPropertyValues (PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }
上面接口提供了三个扩展点,如下:
bean
实例化前
bean
实例化后
bean
属性赋值前
这也是 bean
实例化的生命周期回调方法。
AbstractAutowireCapableBeanFactory#doCreateBean 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 protected Object doCreateBean (final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null ; if (mbd.isSingleton()) { instanceWrapper = this .factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null ) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed" , ex); } mbd.postProcessed = true ; } } boolean earlySingletonExposure = (mbd.isSingleton() && this .allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references" ); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed" , ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false ); if (earlySingletonReference != null ) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this .allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example." ); } } } } try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature" , ex); } return exposedObject; }
AbstractAutowireCapableBeanFactory#createBeanInstance 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 protected BeanWrapper createBeanInstance (String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null ) { return obtainFromSupplier(instanceSupplier, beanName); } if (mbd.getFactoryMethodName() != null ) { return instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false ; boolean autowireNecessary = false ; if (args == null ) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null ) { resolved = true ; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null , null ); } else { return instantiateBean(beanName, mbd); } } Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } ctors = mbd.getPreferredConstructors(); if (ctors != null ) { return autowireConstructor(beanName, mbd, ctors, null ); } return instantiateBean(beanName, mbd); }
上面代码主要判断是使用构函数自动注入,还是使用默认构造函数构造。总结起来以下几种情况会使用构造函数自动注入:
已经缓存过构造函数并且构造函数的参数已经解析过。
候选的构造函数不为空,这里的候选构造函数是通过实现 SmartInstantiationAwareBeanPostProcessor
接口中的 determineCandidateConstructors()
自动注入模式为构造函数自动注入
BeanDefinition
定义了构造函数参数,如 XML 中的 <constructor-arg index="0" value="1"/>
在调用 getBean()
时显示指定了 args
参数
AbstractAutowireCapableBeanFactory#instantiateBean 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 protected BeanWrapper instantiateBean (final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this ; if (System.getSecurityManager() != null ) { beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, parent), getAccessControlContext()); } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed" , ex); } } public Object instantiate (RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null ) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface" ); } try { if (System.getSecurityManager() != null ) { constructorToUse = AccessController.doPrivileged( (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor); } else { constructorToUse = clazz.getDeclaredConstructor(); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found" , ex); } } } return BeanUtils.instantiateClass(constructorToUse); } else { return instantiateWithMethodInjection(bd, beanName, owner); } }
上面代码比较简单,无非就是使用默认的无参构造器去实例化 bean
,并封装成 BeanWrapper
返回。
ConstructorResolver#autowireConstructor 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 protected BeanWrapper autowireConstructor ( String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) { return new ConstructorResolver(this ).autowireConstructor(beanName, mbd, ctors, explicitArgs); } public BeanWrapper autowireConstructor (String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this .beanFactory.initBeanWrapper(bw); Constructor<?> constructorToUse = null ; ArgumentsHolder argsHolderToUse = null ; Object[] argsToUse = null ; if (explicitArgs != null ) { argsToUse = explicitArgs; } else { Object[] argsToResolve = null ; synchronized (mbd.constructorArgumentLock) { constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod; if (constructorToUse != null && mbd.constructorArgumentsResolved) { argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null ) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null ) { argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true ); } } if (constructorToUse == null || argsToUse == null ) { Constructor<?>[] candidates = chosenCtors; if (candidates == null ) { Class<?> beanClass = mbd.getBeanClass(); try { candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors()); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed" , ex); } } if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) { Constructor<?> uniqueCandidate = candidates[0 ]; if (uniqueCandidate.getParameterCount() == 0 ) { synchronized (mbd.constructorArgumentLock) { mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate; mbd.constructorArgumentsResolved = true ; mbd.resolvedConstructorArguments = EMPTY_ARGS; } bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS)); return bw; } } boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null ; int minNrOfArgs; if (explicitArgs != null ) { minNrOfArgs = explicitArgs.length; } else { ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } AutowireUtils.sortConstructors(candidates); int minTypeDiffWeight = Integer.MAX_VALUE; Set<Constructor<?>> ambiguousConstructors = null ; LinkedList<UnsatisfiedDependencyException> causes = null ; for (Constructor<?> candidate : candidates) { int parameterCount = candidate.getParameterCount(); if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) { break ; } if (parameterCount < minNrOfArgs) { continue ; } ArgumentsHolder argsHolder; Class<?>[] paramTypes = candidate.getParameterTypes(); if (resolvedValues != null ) { try { String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount); if (paramNames == null ) { ParameterNameDiscoverer pnd = this .beanFactory.getParameterNameDiscoverer(); if (pnd != null ) { paramNames = pnd.getParameterNames(candidate); } } argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1 ); } catch (UnsatisfiedDependencyException ex) { if (logger.isTraceEnabled()) { logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex); } if (causes == null ) { causes = new LinkedList<>(); } causes.add(ex); continue ; } } else { if (parameterCount != explicitArgs.length) { continue ; } argsHolder = new ArgumentsHolder(explicitArgs); } int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); if (typeDiffWeight < minTypeDiffWeight) { constructorToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousConstructors = null ; } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { if (ambiguousConstructors == null ) { ambiguousConstructors = new LinkedHashSet<>(); ambiguousConstructors.add(constructorToUse); } ambiguousConstructors.add(candidate); } } if (constructorToUse == null ) { if (causes != null ) { UnsatisfiedDependencyException ex = causes.removeLast(); for (Exception cause : causes) { this .beanFactory.onSuppressedException(cause); } throw ex; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Could not resolve matching constructor " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)" ); } else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Ambiguous constructor matches found in bean '" + beanName + "' " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + ambiguousConstructors); } if (explicitArgs == null && argsHolderToUse != null ) { argsHolderToUse.storeCache(mbd, constructorToUse); } } Assert.state(argsToUse != null , "Unresolved constructor arguments" ); bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse)); return bw; }
上面代码的功能主要如下:
构造函数参数的确定
如果 explicitArgs
参数不为空,那就可以直接确定参数。因为 explicitArgs
参数是在调用 getBean()
时手动指定的,这个主要用于静态工厂方法的调用。
缓存中不为空,那么可以直接拿过来使用。
BeanDefinition
中读取,我们所定义的 bean
都会生成一个 BeanDefinition
,其中记录了定义了构造函数参数通过 getConstructorArgumentValues()
获取。
构造函数的确定。经过第一步已经确定构造函数的参数,接下来就是用参数个数在所有的构造函数中锁定对应的构造函数。匹配之前会对构造函数进行排序,首先是 public
构造函数且参数个数从多到少,然后是非public
构造函数且参数个数有多到少。这样可以迅速判断排在后面的构造函数参数个数是否符合条件。
根据对应的构造函数转换对应的参数类型。
根据实例化策略以及得到的构造函数和构造函数参数实例化 bean
。
ConstructorResolver#resolveConstructorArguments 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 private int resolveConstructorArguments (String beanName, RootBeanDefinition mbd, BeanWrapper bw, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) { TypeConverter customConverter = this .beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this .beanFactory, beanName, mbd, converter); int minNrOfArgs = cargs.getArgumentCount(); for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) { int index = entry.getKey(); if (index < 0 ) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid constructor argument index: " + index); } if (index > minNrOfArgs) { minNrOfArgs = index + 1 ; } ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue(); if (valueHolder.isConverted()) { resolvedValues.addIndexedArgumentValue(index, valueHolder); } else { Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument" , valueHolder.getValue()); ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder); } } for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) { if (valueHolder.isConverted()) { resolvedValues.addGenericArgumentValue(valueHolder); } else { Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument" , valueHolder.getValue()); ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder( resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); resolvedValues.addGenericArgumentValue(resolvedValueHolder); } } return minNrOfArgs; }
上面代码主要将 indexedArgumentValues
和 genericArgumentValues
的值调用 resolveValueIfNecessary()
进行解析;resolveValueIfNecessary()
主要解析参数的类型,比如 ref
属性引用的 beanName
会通过 getBean()
返回实例。
ConstructorResolver#createArgumentArray 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 private ArgumentsHolder createArgumentArray ( String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException { TypeConverter customConverter = this .beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); ArgumentsHolder args = new ArgumentsHolder(paramTypes.length); Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length); Set<String> autowiredBeanNames = new LinkedHashSet<>(4 ); for (int paramIndex = 0 ; paramIndex < paramTypes.length; paramIndex++) { Class<?> paramType = paramTypes[paramIndex]; String paramName = (paramNames != null ? paramNames[paramIndex] : "" ); ConstructorArgumentValues.ValueHolder valueHolder = null ; if (resolvedValues != null ) { valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders); if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) { valueHolder = resolvedValues.getGenericArgumentValue(null , null , usedValueHolders); } } if (valueHolder != null ) { usedValueHolders.add(valueHolder); Object originalValue = valueHolder.getValue(); Object convertedValue; if (valueHolder.isConverted()) { convertedValue = valueHolder.getConvertedValue(); args.preparedArguments[paramIndex] = convertedValue; } else { MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex); try { convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam); } catch (TypeMismatchException ex) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(valueHolder.getValue()) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage()); } Object sourceHolder = valueHolder.getSource(); if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) { Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue(); args.resolveNecessary = true ; args.preparedArguments[paramIndex] = sourceValue; } } args.arguments[paramIndex] = convertedValue; args.rawArguments[paramIndex] = originalValue; } else { MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex); if (!autowiring) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Ambiguous argument values for parameter of type [" + paramType.getName() + "] - did you specify the correct bean references as arguments?" ); } try { Object autowiredArgument = resolveAutowiredArgument( methodParam, beanName, autowiredBeanNames, converter, fallback); args.rawArguments[paramIndex] = autowiredArgument; args.arguments[paramIndex] = autowiredArgument; args.preparedArguments[paramIndex] = autowiredArgumentMarker; args.resolveNecessary = true ; } catch (BeansException ex) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex); } } } for (String autowiredBeanName : autowiredBeanNames) { this .beanFactory.registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via " + (executable instanceof Constructor ? "constructor" : "factory method" ) + " to bean named '" + autowiredBeanName + "'" ); } } return args; }
上面代码判断构造函数如果有匹配的参数会转换成对应类型,如果没有匹配的参数,多半是构造函数自动注入,通过 resolveAutowiredArgument()
去查找 bean
并返回实例。
ConstructorResolver#resolveAutowiredArgument 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 protected Object resolveAutowiredArgument (MethodParameter param, String beanName, @Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) { Class<?> paramType = param.getParameterType(); if (InjectionPoint.class.isAssignableFrom(paramType)) { InjectionPoint injectionPoint = currentInjectionPoint.get(); if (injectionPoint == null ) { throw new IllegalStateException("No current InjectionPoint available for " + param); } return injectionPoint; } try { return this .beanFactory.resolveDependency( new DependencyDescriptor(param, true ), beanName, autowiredBeanNames, typeConverter); } catch (NoUniqueBeanDefinitionException ex) { throw ex; } catch (NoSuchBeanDefinitionException ex) { if (fallback) { if (paramType.isArray()) { return Array.newInstance(paramType.getComponentType(), 0 ); } else if (CollectionFactory.isApproximableCollectionType(paramType)) { return CollectionFactory.createCollection(paramType, 0 ); } else if (CollectionFactory.isApproximableMapType(paramType)) { return CollectionFactory.createMap(paramType, 0 ); } } throw ex; } }
上面代码我们一般只需要重点关注 this.beanFactory.resolveDependency()
这个方法,这个就是解决依赖注入的秘密所在。
DefaultListableBeanFactory#resolveDependency 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public Object resolveDependency (DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null ) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } }
上面代码主要判断如果需要注入的 bean
的类型是 Optional
、ObjectFactory
、ObjectProvider
、Provider
会做特殊的处理,一般情况下注入的 bean
会走最后的 doResolveDependency()
。 还有一个比较重要的参数 DependencyDescriptor
,这个类就是依赖描述符,存储了需要注入 bean
的类型、构造器参数的下标(构造器注入该值不为空)、是否必需、字段名称(字段注入该值不为空)、方法名称(setter
方法注入该值不为空)等。
DefaultListableBeanFactory#doResolveDependency 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 public Object doResolveDependency (DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Object shortcut = descriptor.resolveShortcut(this ); if (shortcut != null ) { return shortcut; } Class<?> type = descriptor.getDependencyType(); Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null ) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null ); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); try { return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); } catch (UnsupportedOperationException ex) { return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) :converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } } Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null ) { return multipleBeans; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null ; } String autowiredBeanName; Object instanceCandidate; if (matchingBeans.size() > 1 ) { autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null ) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans); } else { return null ; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null ) { autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this ); } Object result = instanceCandidate; if (result instanceof NullBean) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null ; } if (!ClassUtils.isAssignableValue(type, result)) { throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); } return result; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
上面代码才是真正去获取需要注入的 bean
,大概分为以下几个步骤:
查看是否有快捷方式获取注入 bean
是否为空,不为空直接返回。这里的快捷方式是通过继承 DependencyDescriptor
并重写 resolveShortcut()
来实现。
如果参数使用 @Value
注解修饰了,如果获取到值直接返回。
解析 MultipleBean
,这里的 MultipleBean
一般是 Array
、Collection
、Map
这种,不为空直接返回。
根据类型找到所有匹配的 bean
,matchingBeans
中 key
为 beanName
,value
的值有两种情况,如果bean已经缓存了实例(例如单例bean会缓存其实例),就是bean的实例,否则就是对应的class对象)。
matchingBeans
为空,判断需要注入的 bean
是否是必须的,如果是抛出异常,否则返回 null
。
matchingBeans
长度大于1,代表有多个候选者;选择最佳的候选者,规则是:
首先查找 primary
属性为 true
的。
查找优先级最高的,实现 PriorityOrdered
接口或者标注 @Priority
注解的。
查找名称匹配的。
只有一个候选者,直接使用。
如果需要注入的 bean
没有缓存实例,那么 instanceCandidate
是一个 Class
对象,再根据 getBean()
去获取对应的实例。
最终返回需要注入的 bean
实例。
AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors 1 2 3 4 5 6 7 8 protected void applyMergedBeanDefinitionPostProcessors (RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }
上面代码很简单,无非就是拿到所有注册的 BeanPostProcessor
,然后遍历判断是否是 MeragedBeanDefinitionPostProcessor
类型,是的话进行 BeanDefinition
合并后的方法回调,在这个回调方法内你可以对指定 bean
的 BeanDefinition
做一些修改。
下面我们简单看一下 MergedBeanDefinitionPostProcessor
接口中的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor { void postProcessMergedBeanDefinition (RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) ; default void resetBeanDefinition (String beanName) { } }
DefaultSingletonBeanRegistry#addSingletonFactory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 protected void addSingletonFactory (String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null" ); synchronized (this .singletonObjects) { if (!this .singletonObjects.containsKey(beanName)) { this .singletonFactories.put(beanName, singletonFactory); this .earlySingletonObjects.remove(beanName); this .registeredSingletons.add(beanName); } } }
上面代码将 ObjectFactory
加入 singletonFactories
缓存中,以下是 singletonFactories
的声明:
1 2 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16 );
下面以一个简单的AB循环依赖为例,类A中含有属性类B,而类B中又会含有属性类A。那么初始化 beanA 的过程如下图所示:
Spring 解决循环依赖的方法就在 addSingletonFactory()
和 getBean()
方法中。首先创建 beanA
时,将实例化好的 beanA
封装成 ObjectFactory
放入 singletonFactories
缓存中,接着进行属性填充;因为依赖 beanB
所以先去实例化 beanB
,接着 beanB
属性填充,发现需要 beanA
就调用 getBean()
去获取 beanA
实例。上篇文章讲过 getBean()
会首先判断缓存中是否有已经创建好的 bean
或者是 beanFactory
,如下代码所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 protected Object getSingleton (String beanName, boolean allowEarlyReference) { Object singletonObject = this .singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this .singletonObjects) { singletonObject = this .earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this .singletonFactories.get(beanName); if (singletonFactory != null ) { singletonObject = singletonFactory.getObject(); this .earlySingletonObjects.put(beanName, singletonObject); this .singletonFactories.remove(beanName); } } } } return singletonObject; }
因为 beanA
与 beanB
中的 beanA
所表示的属性地址是一样的,所以在 beanA
中创建好的属性填充自然可以通过 beanB
中的 beanA
获取,这样就解决了循环依赖的问题。
AbstractAutowireCapableBeanFactory#getEarlyBeanReference 1 2 3 4 5 6 7 8 9 10 11 12 protected Object getEarlyBeanReference (String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }
上面代码很简单,就是判断是否有注册 InstantiationAwareBeanPostProcessor
的实现,如果有遍历找到类型是 SmartInstantiationAwareBeanPostProcessor
调用 getEarlyBeanReference()
返回 bean
的实例。
这里又是一个 Spring 的扩展点,其中我们熟知的 AOP 就是在这里将 advice
动态织入 bean
中,若没有则直接返回 bean
,不做任何处理。
AbstractAutowireCapableBeanFactory#populateBean 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 protected void populateBean (String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null ) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance" ); } else { return ; } } if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return ; } } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null ); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null ; if (hasInstAwareBpps) { if (pvs == null ) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null ) { if (filteredPds == null ) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null ) { return ; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null ) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null ) { applyPropertyValues(beanName, mbd, bw, pvs); } }
上面代码首先会调用 bean
的实例化后生命周期回调方法,如果返回 false
会跳过下面的属性赋值阶段。下面我们简单看一下 InstantiationAwareBeanPostProcessors
的接口定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { @Nullable default Object postProcessBeforeInstantiation (Class<?> beanClass, String beanName) throws BeansException { return null ; } default boolean postProcessAfterInstantiation (Object bean, String beanName) throws BeansException { return true ; } @Nullable default PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) throws BeansException { return null ; } @Deprecated @Nullable default PropertyValues postProcessPropertyValues ( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }
接着判断是否是按 名称 或者 类型 自动注入属性并填入 newPvs
中,接着调用 bean
属性填充前的生命周期回调。属性填充前生命周期回调方法有两个 postProcessProperties()
和 postProcessPropertyValues()
,第一个是 Spring 5.1 新加的,后面的是老的,已经被标记为过时;首先会调用 postProcessProperties()
如果返回空调用 postProcessPropertyValues()
,否则直接使用返回的 PropertyValues
;postProcessPropertyValues()
如果返回空会直接跳过属性填充阶段,不为空直接使用返回的 PropertyValues
。
AbstractAutowireCapableBeanFactory#autowireByName 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 protected void autowireByName ( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { if (containsBean(propertyName)) { Object bean = getBean(propertyName); pvs.add(propertyName, bean); registerDependentBean(propertyName, beanName); if (logger.isTraceEnabled()) { logger.trace("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'" ); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found" ); } } } }
AbstractAutowireCapableBeanFactory#autowireByType 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 protected void autowireByType (String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null ) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4 ); String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); if (Object.class != pd.getPropertyType()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null ) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { registerDependentBean(autowiredBeanName, beanName); if (logger.isTraceEnabled()) { logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'" ); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
AbstractAutowireCapableBeanFactory#applyPropertyValues 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 protected void applyPropertyValues (String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { if (pvs.isEmpty()) { return ; } if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } MutablePropertyValues mpvs = null ; List<PropertyValue> original; if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; if (mpvs.isConverted()) { try { bw.setPropertyValues(mpvs); return ; } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values" , ex); } } original = mpvs.getPropertyValueList(); } else { original = Arrays.asList(pvs.getPropertyValues()); } TypeConverter converter = getCustomTypeConverter(); if (converter == null ) { converter = bw; } BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this , beanName, mbd, converter); List<PropertyValue> deepCopy = new ArrayList<>(original.size()); boolean resolveNecessary = false ; for (PropertyValue pv : original) { if (pv.isConverted()) { deepCopy.add(pv); } else { String propertyName = pv.getName(); Object originalValue = pv.getValue(); if (originalValue == AutowiredPropertyMarker.INSTANCE) { Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod(); if (writeMethod == null ) { throw new IllegalArgumentException("Autowire marker for property without write method: " + pv); } originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0 ), true ); } Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); } else { resolveNecessary = true ; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values" , ex); } }
上面代码主要就是进行属性的类型转换,最后填充 bean
的属性值,这里一般就是利用反射使用 set()
去给属性赋值。
AbstractAutoCapableBeanFactory#initializeBean 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 protected Object initializeBean (final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null ) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null ; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null ), beanName, "Invocation of init method failed" , ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
AbstractAutowireCapableBeanFactory#invokeAwareMethods 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private void invokeAwareMethods (final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null ) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this ); } } }
实现这些 Aware
接口的 bean
的被初始化之前,可以取得一些相对应的资源,比如 beanName
、beanFactory
等。
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public Object applyBeanPostProcessorsBeforeInitialization (Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null ) { return result; } result = current; } return result; }
AbstractAutowireCapableBeanFactory#invokeInitMethods 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 protected void invokeInitMethods (String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet" ))) { if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'" ); } if (System.getSecurityManager() != null ) { try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((InitializingBean) bean).afterPropertiesSet(); return null ; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet" .equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } }
综合上面的代码来看,bean
初始化阶段流程主要如下:
@PostConstruct
注解修饰的方法,前提是注解驱动
实现 InitializingBean
接口的 afterPropertySet()
自定义初始化方法,例如 XML 中的 init-method
属性设置的方法
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public Object applyBeanPostProcessorsAfterInitialization (Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null ) { return result; } result = current; } return result; }
下面我们简单看一下 BeanPostProcessor
接口,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { return bean; } }
BeanPostProcessor
接口比较简单,就提供了两个接口回调,一个初始化前,一个初始化后。但是其它的 PostProcessor
大部门以此为基础,继承自 BeanPostProcessor
。
AbstractBeanFactory#registerDisposableBeanIfNecessary 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 protected void registerDisposableBeanIfNecessary (String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null ); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { Scope scope = this .scopes.get(mbd.getScope()); if (scope == null ) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'" ); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
DisposableBeanAdapter构造函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 public DisposableBeanAdapter (Object bean, String beanName, RootBeanDefinition beanDefinition, List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) { Assert.notNull(bean, "Disposable bean must not be null" ); this .bean = bean; this .beanName = beanName; this .invokeDisposableBean = (this .bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy" )); this .nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed(); this .acc = acc; String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition); if (destroyMethodName != null && !(this .invokeDisposableBean && "destroy" .equals(destroyMethodName)) && !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) { this .destroyMethodName = destroyMethodName; Method destroyMethod = determineDestroyMethod(destroyMethodName); if (destroyMethod == null ) { if (beanDefinition.isEnforceDestroyMethod()) { throw new BeanDefinitionValidationException("Could not find a destroy method named '" + destroyMethodName + "' on bean with name '" + beanName + "'" ); } } else { Class<?>[] paramTypes = destroyMethod.getParameterTypes(); if (paramTypes.length > 1 ) { throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + beanName + "' has more than one parameter - not supported as destroy method" ); } else if (paramTypes.length == 1 && boolean .class != paramTypes[0 ]) { throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + beanName + "' has a non-boolean parameter - not supported as destroy method" ); } destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod); } this .destroyMethod = destroyMethod; } this .beanPostProcessors = filterPostProcessors(postProcessors, bean); }
DisposableBeanAdapter#filterPostProcessors 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private List<DestructionAwareBeanPostProcessor> filterPostProcessors (List<BeanPostProcessor> processors, Object bean) { List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null ; if (!CollectionUtils.isEmpty(processors)) { for (BeanPostProcessor processor : processors) { if (processor instanceof DestructionAwareBeanPostProcessor) { DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor; if (dabpp.requiresDestruction(bean)) { filteredPostProcessors.add(dabpp); } } } } return filteredPostProcessors; }
上面的代码主要就是判断如果 BeanPostProcessor
是 DestructionAwareBeanPostProcessor
并且 requiresDestruction()
返回 true
代表需要通过后置处理器进行销毁实例,将该 BeanPostProcessor
添加到 filteredPostProcessors
中。
下面我们简单看一下 DestructionAwareBeanPostProcessor
接口的定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor { void postProcessBeforeDestruction (Object bean, String beanName) throws BeansException ; default boolean requiresDestruction (Object bean) { return true ; } }
可以看到其也是继承于 BeanPostProcessor
,主要提供两个方法一个是 bean
销毁前的生命周期方法回调,另一个是判定 bean
实例是否要由此后置处理器进行实例的销毁。
DefaultListableBeanFactory#destroySingletons 因为基本上 BeanFactory
就只会使用 DefaultListableBeanFactory
这一个最终实现,所以我们这里分析一下这里的销毁单例 bean
的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 public void destroySingletons () { super .destroySingletons(); updateManualSingletonNames(Set::clear, set -> !set.isEmpty()); clearByTypeCache(); } public void destroySingletons () { if (logger.isTraceEnabled()) { logger.trace("Destroying singletons in " + this ); } synchronized (this .singletonObjects) { this .singletonsCurrentlyInDestruction = true ; } String[] disposableBeanNames; synchronized (this .disposableBeans) { disposableBeanNames = StringUtils.toStringArray(this .disposableBeans.keySet()); } for (int i = disposableBeanNames.length - 1 ; i >= 0 ; i--) { destroySingleton(disposableBeanNames[i]); } this .containedBeanMap.clear(); this .dependentBeanMap.clear(); this .dependenciesForBeanMap.clear(); clearSingletonCache(); } public void destroySingleton (String beanName) { removeSingleton(beanName); DisposableBean disposableBean; synchronized (this .disposableBeans) { disposableBean = (DisposableBean) this .disposableBeans.remove(beanName); } destroyBean(beanName, disposableBean); } protected void destroyBean (String beanName, @Nullable DisposableBean bean) { Set<String> dependencies; synchronized (this .dependentBeanMap) { dependencies = this .dependentBeanMap.remove(beanName); } if (dependencies != null ) { if (logger.isTraceEnabled()) { logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); } for (String dependentBeanName : dependencies) { destroySingleton(dependentBeanName); } } if (bean != null ) { try { bean.destroy(); } catch (Throwable ex) { if (logger.isWarnEnabled()) { logger.warn("Destruction of bean with name '" + beanName + "' threw an exception" , ex); } } } Set<String> containedBeans; synchronized (this .containedBeanMap) { containedBeans = this .containedBeanMap.remove(beanName); } if (containedBeans != null ) { for (String containedBeanName : containedBeans) { destroySingleton(containedBeanName); } } synchronized (this .dependentBeanMap) { for (Iterator<Map.Entry<String, Set<String>>> it = this .dependentBeanMap.entrySet().iterator(); it.hasNext();) { Map.Entry<String, Set<String>> entry = it.next(); Set<String> dependenciesToClean = entry.getValue(); dependenciesToClean.remove(beanName); if (dependenciesToClean.isEmpty()) { it.remove(); } } } this .dependenciesForBeanMap.remove(beanName); }
DisposableBeanAdapter#destroy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public void destroy () { if (!CollectionUtils.isEmpty(this .beanPostProcessors)) { for (DestructionAwareBeanPostProcessor processor : this .beanPostProcessors) { processor.postProcessBeforeDestruction(this .bean, this .beanName); } } if (this .invokeDisposableBean) { if (logger.isTraceEnabled()) { logger.trace("Invoking destroy() on bean with name '" + this .beanName + "'" ); } try { if (System.getSecurityManager() != null ) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this .bean).destroy(); return null ; }, this .acc); } else { ((DisposableBean) this .bean).destroy(); } } catch (Throwable ex) { String msg = "Invocation of destroy method failed on bean with name '" + this .beanName + "'" ; if (logger.isDebugEnabled()) { logger.warn(msg, ex); } else { logger.warn(msg + ": " + ex); } } } if (this .destroyMethod != null ) { invokeCustomDestroyMethod(this .destroyMethod); } else if (this .destroyMethodName != null ) { Method methodToInvoke = determineDestroyMethod(this .destroyMethodName); if (methodToInvoke != null ) { invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } }
总得来说上面方法主要分为三步:
回调实现了 DestructionAwareBeanPostProcessor
接口的 postProcessBeforeDestruction
方法,InitDestoryAnnotationBeanPostProcessor
的 postProcessBeforeDestruction()
中会执行标注了 @PreDestory
注解的方法。
调用实现了 DisposableBean
接口的 destroy()
。
调用自定义实现的 destroyMethod
,例如 XML 中的 destory
属性指定的方法
总结 本文主要介绍了 createBean()
流程,我们可以重新梳理一下思路:
进行 bean
的实例化前方法回调,如果返回非空,跳过后面步骤
创建 bean
的实例,如果是构造函数注入会选择最适合的构造函数进行参数自动注入,否则调用默认的无参构造进行实例化 bean
。
如果 bean
允许提前曝光,将 beanName
对应的 ObjectFactory
放入 singletonFactories
缓存中。
bean
的属性赋值阶段,首先调用 bean
实例化后方法回调,返回 false
会跳过后面的赋值阶段;判断是否是按照名称或者类型自动注入,是则进行属性自动注入。接着调用处理属性值的后置处理方法,首先调用Spring5.1版本新加的方法,如果返回的属性为空,再调用以前版本的方法,如果为空,直接返回,没必要再走后面的实际赋值阶段。
bean
的初始化阶段,首先是调用可以获取相应资源的一些 Aware
接口;然后调用 bean
初始化前回调方法 ( InitDestroyAnnotationBeanPostProcessor
的 postProcessBeforeInitialization()
中会执行 标注了 @PostConstruct
注解的方法),接着调用重写的 afterPropertiesSet()
和自定义的初始化方法;最后进行 bean
初始化后回调方法。
注册销毁 bean
的方法。
最后返回 bean
的实例。
最后,我模仿 Spring 写了一个精简版,代码会持续更新。地址:https://github.com/leisurexi/tiny-spring 。访问新博客地址,观看效果更佳 https://leisurexi.github.io/
参考